package de.fhaugsburg.games.boardgames;

import java.util.Iterator;


import de.fhaugsburg.games.boardgames.gameexceptions.OutsideBoardException;

import de.fhaugsburg.games.boardgames.scrabble.managment.GridPoint;

public abstract class Board {
	protected Square[][] squares;
	protected int height;
	protected int width;

	public Board(int rows, int columns) {
		squares = new Square[rows][columns];
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				squares[i][j] = new Square();
			}

		}
		this.height = rows;
		this.width = columns;
	}

	public void reset() {
		for (int i = 0; i < height; i++) {
			for (int k = 0; k < width; k++) {
				squares[i][k] = new Square();
			}
		}
	}

	public void putPiece(IPiece piece, int row, int column) throws OutsideBoardException {
		if (isOnTheBoard(row, column) && isEmpty(row, column)) {
			squares[row][column].put(piece);
		} else {

			throw new OutsideBoardException();

		}

	}
	public void putPiece(IPiece piece, GridPoint point){
		if (isOnTheBoard( point) && isEmpty(point)){
			squares[point.row][point.col].put(piece);
		}else{
			throw new OutsideBoardException();
		}
	}

	public IPiece getPiece(int row, int column) {

		return squares[row][column].getPiece();

	}
	public IPiece getPiece(GridPoint g) {
		return squares[g.row][g.col].getPiece();
	}

	public SquareDetails getDetails(int row, int column) {
		return squares[row][column].getDetails();
	}
	public SquareDetails getDetails(GridPoint gridPoint){
		return squares[gridPoint.row][gridPoint.col].getDetails();
	}

	public void movePiece(int fromRow, int fromColumn, int toRow, int toColumn) {
		squares[toRow][toColumn] = squares[fromRow][fromColumn];
		squares[fromRow][fromColumn].removePiece();
	}

	public IPiece removePiece(int row, int column) {
		return squares[row][column].removePiece();
	}
	public IPiece removePiece(GridPoint point){
		return squares[point.row][point.col].removePiece();
	}

	public boolean isOnTheBoard(int row, int column) {
		if (row >= this.height || row < 0 || column >= this.width || column < 0) {
			return false;
		} else {
			return true;
		}
	}
	public boolean isOnTheBoard(GridPoint gridPoint){
		if (gridPoint.row >= this.height || gridPoint.row < 0 || gridPoint.col >= this.width || gridPoint.col < 0) {
			return false;
		} else {
			return true;
		}
	}

	public boolean isEmpty(int row, int column) {
		if (squares[row][column].isEmpty()) {
			return true;
		} else {
			return false;
		}
	}
	public boolean isEmpty(GridPoint gridPoint){
		if (squares[gridPoint.row][gridPoint.col].isEmpty()) return true;
		return false;
	}
	public Square getSquare(GridPoint gridPoint){
		return squares[gridPoint.row][gridPoint.col];
	}

	public int getHeight() {
		return height;
	}

	public int getWidth() {
		return width;
	}
	public Iterator<GridPoint> iterator(GridPoint startPoint, GridPoint direction){
		return new DirIterator<GridPoint>(startPoint, direction);		
	}
	
	private class DirIterator<T> implements Iterator<GridPoint>{
		private GridPoint direction, currentLocation;
		
		public DirIterator(GridPoint startPoint, GridPoint direction){
			super();
			this.currentLocation = startPoint;
			this.direction = direction;
//			if (hasNext()){
//				next();
//			}
		}
		
		public boolean hasNext(){
			if (Board.this.isOnTheBoard(currentLocation.plus(direction))&& Board.this.isEmpty(currentLocation.plus(direction)) == false) {
				return true;
			}else{
				return false;
			}
			
		}
		
		public GridPoint next(){
			
			currentLocation = currentLocation.plus(direction);
			return currentLocation;
		}
		
		public void remove(){			
		}
	}
public boolean equals(Board board){
		
		for (int i = 0; i < this.height; i++) {
			for (int j = 0; j < this.width; j++) {
				if(squares[i][j].equals(board.getSquare(new GridPoint(i,j))) == false){
					return false;
				}
			}

		}
		return true;
	}
}
